﻿using MobiSms.Infrastructure;
using MobiSms.WebUtility;
using System;
using System.Data.Linq.Mapping;
using System.ServiceModel;

namespace MobiSms.DataModel
{
    [Table(Name = "T_SN")]
    public class SerialInfo : NotificationObject
    {
        #region Constructor
        WebServiceSoapClient client = new WebServiceSoapClient(WebBindingConfig.HttpBinding, new EndpointAddress(WebBindingConfig.Url));

        public SerialInfo()
        {
            client.BalanceCompleted -= client_BalanceCompleted;
            client.BalanceCompleted += client_BalanceCompleted;

            client.RegisterCompleted -= client_RegisterCompleted;
            client.RegisterCompleted += client_RegisterCompleted;
            //GetBalance();
        }
        #endregion

        #region Fields
        private string _guid = System.Guid.NewGuid().ToString();
        private string _serialNumber = string.Empty;
        private string _password = string.Empty;
        private string _serviceCode;
        private string _signature;
        private Int64 _balance = 0;
        private string _province;
        private string _city;
        private string _address;
        private string _fullname;
        private string _linkman;
        private string _phone;
        private string _mobile;
        private string _email;
        private Int64 _sentCount = 0;
        private string _extension = string.Empty;
        #endregion

        #region Properties
        /// <summary>
        /// Get or set the identity key;
        /// </summary>
        [Column(IsPrimaryKey = true)]
        public string Guid
        {
            get { return _guid; }
            set
            {
                _guid = value;
                RaisePropertyChanged(() => Guid);
            }
        }

        /// <summary>
        /// Get or set the serial number;
        /// </summary>
        [Column]
        public string SerialNumber
        {
            get { return _serialNumber.ToUpper(); }
            set
            {
                _serialNumber = value;
                RaisePropertyChanged(() => SerialNumber);
                RaisePropertyChanged(() => Available);
            }
        }

        /// <summary>
        /// Get or set the password;
        /// </summary>
        [Column]
        public string Password
        {
            get { return _password; }
            set
            {
                _password = value;
                RaisePropertyChanged(() => Password);
                RaisePropertyChanged(() => Available);
            }
        }

        /// <summary>
        /// Get or ser then service code;
        /// </summary>
        [Column]
        public string ServiceCode
        {
            get { return _serviceCode; }
            set
            {
                _serviceCode = value;
                RaisePropertyChanged(() => ServiceCode);
            }
        }

        /// <summary>
        /// Get or set the signature, this value will automatically used in message.
        /// </summary>
        [Column]
        public string Signature
        {
            get { return _signature; }
            set
            {
                _signature = value;
                RaisePropertyChanged(() => Signature);
            }
        }

        /// <summary>
        /// Get or set the history sent count;
        /// </summary>
        [Column]
        public Int64 SentCount
        {
            get { return _sentCount; }
            set
            {
                _sentCount = value;
                RaisePropertyChanged(() => SentCount);
            }
        }

        [Column]
        public string Extension
        {
            get { return _extension; }
            set
            {
                _extension = value;
                RaisePropertyChanged(() => Extension);
            }
        }

        /// <summary>
        /// Get or set balance of the serial number.
        /// The balance will be refreshed when constructed.
        /// </summary>
        public Int64 Balance
        {
            get { return _balance; }
            set
            {
                _balance = value;
                RaisePropertyChanged(() => Balance);
            }
        }

        public string Province
        {
            get { return _province; }
            set
            {
                _province = value;
                RaisePropertyChanged(() => Province);
            }
        }

        public string City
        {
            get { return _city; }
            set
            {
                _city = value;
                RaisePropertyChanged(() => City);
            }
        }

        public string Address
        {
            get { return _address; }
            set
            {
                _address = value;
                RaisePropertyChanged(() => Address);
            }
        }

        public string Fullname
        {
            get { return _fullname; }
            set
            {
                _fullname = value;
                RaisePropertyChanged(() => Fullname);
            }
        }

        public string Linkman
        {
            get { return _linkman; }
            set
            {
                _linkman = value;
                RaisePropertyChanged(() => Linkman);
            }
        }

        public string Phone
        {
            get { return _phone; }
            set
            {
                _phone = value;
                RaisePropertyChanged(() => Phone);
            }
        }

        public string Mobile
        {
            get { return _mobile; }
            set
            {
                _mobile = value;
                RaisePropertyChanged(() => Mobile);
            }
        }

        public string Email
        {
            get { return _email; }
            set
            {
                _email = value;
                RaisePropertyChanged(() => Email);
            }
        }

        public bool Available
        {
            get
            {
                return !string.IsNullOrEmpty(SerialNumber.Trim()) && Password.Trim().Length == 6;
            }
        }
        #endregion

        #region Events
        public event EventHandler<PropertyArgs> ValueChanged = delegate { };

        public event EventHandler<RegisterResultArgs> RegisterCompleted = delegate { };

        protected override void RaisePropertyChanged(string propertyName)
        {
            base.RaisePropertyChanged(propertyName);
            ValueChanged.Invoke(this, new PropertyArgs()
            {
                Property = GetType().GetProperty(propertyName),
                Value = GetType().GetProperty(propertyName).GetValue(this, null)
            });
        }

        private void client_BalanceCompleted(object sender, BalanceCompletedEventArgs e)
        {
            if (e.Result.code == 0)
            {
                Balance = Convert.ToInt64(e.Result.balance);
            }
        }

        private void client_RegisterCompleted(object sender, RegisterCompletedEventArgs e)
        {
            RegisterCompleted.Invoke(this, new RegisterResultArgs() { Result = e.Result.code == 0 });
        }
        #endregion

        #region Methods
        public void Register()
        {
            client.RegisterAsync(SerialNumber, Password, Province, City, Address, Fullname, Linkman, Phone, Mobile, Email, Signature);
        }

        public void GetBalance()
        {
            if (!string.IsNullOrWhiteSpace(SerialNumber) && !string.IsNullOrWhiteSpace(Password))
            {
                client.BalanceAsync(SerialNumber, Password);
            }
        }
        #endregion
    }
}
